import React from 'react';
import { NetworkStatus } from '@apollo/client';
import { Box, ListBase } from '@nova-hf/ui';
import { ErrorBanner } from 'beta/components/error/ErrorBanner';
import Authentication from 'beta/store/authentication';
import UI from 'beta/store/ui';
import { parseMainColor } from 'beta/utils/typeGuards';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import {
  ContractItemType,
  ContractStatus,
  DeviceContractItem,
  ServiceContractItem,
  ServiceStatus as FiberServiceStatus,
  ServiceStatus,
  useContractsQuery,
  useFiberServiceIsMovingQuery,
  useGetTerminationsQuery,
  useServiceQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

import { FiberStatus } from './Overview/FiberStatus';
import MonthlySummary from './Overview/MonthlySummary';
import UsageSummary from './Overview/UsageSummary';

import Discounts from './Discounts';
import FiberAppointment from './FiberAppointment';
import FiberDevices from './FiberDevices';
import FiberItems from './FiberItems';
import FiberMoveOrderContainer from './FiberMoveOrderContainer';
import FiberRestrictions from './FiberRestrictions';
import FiberServiceActivate from './FiberServiceActivate';
import FiberServiceTermination from './FiberServiceTermination';
import PendingPayerChanges from './PendingPayerChanges';

export const ROUTER_VARIANT_ID = 'fiber-router';
export const ROUTER_25X_VAIANT_ID = 'fiber-router-25x';
export const KASTARI_VARIANT_ID = 'kastari';
export const COMPANY_KASTARI_ID = 'company-extender';
export const COMPANY_KASTARI_PRO_ID = 'company-extender-pro';
export const COMPANY_ROUTER_ID = 'company-fiber-router';
export const COMPANY_ROUTER_PRO_ID = 'company-fiber-router-pro';
export const COMPANY_SWITCH = 'company-switch-fpoe';

type FiberServiceContainerProps = {
  ui?: UI;
  authentication?: Authentication;
};

const FiberServiceContainer = ({ ui, authentication }: FiberServiceContainerProps) => {
  const { t } = useTranslation(['services', 'errors', 'fiber']);
  const router = useRouter();
  const serviceId = typeof router?.query?.serviceId === 'string' ? router?.query?.serviceId : '';
  const customerId = typeof router?.query?.customerId === 'string' ? router?.query?.customerId : '';
  const isStaff = authentication?.isStaff;

  const { data, loading, error, networkStatus, refetch } = useServiceQuery({
    variables: {
      serviceId: serviceId,
    },
    skip: !serviceId,
  });
  const { data: contractData, refetch: contractsRefetch } = useContractsQuery({
    variables: {
      input: {
        serviceId,
        customerId,
      },
    },
    skip: !serviceId || !customerId,
  });

  const { data: terminationsData, refetch: terminationRefetch } = useGetTerminationsQuery({
    variables: {
      input: { serviceId },
    },
  });

  const termination = terminationsData?.terminations?.find(
    (termination) => !termination.isProcessed && !termination.isCancelled,
  );
  const hasTermination = !!termination;

  const service = data?.service?.__typename == 'FiberService' ? data?.service : undefined;

  const activeOrPendingContract = contractData?.contracts?.contracts?.find(
    (contract) =>
      contract.status === ContractStatus.Active || contract.status === ContractStatus.Pending,
  );
  const hasTwoActiveServices = activeOrPendingContract?.contractItems?.filter(
    (item) =>
      item?.type === ContractItemType.Service &&
      item.status === ContractStatus.Active &&
      item?.variantId?.includes('ljos-'),
  );

  const isServiceContractItem = (item: any): item is ServiceContractItem => {
    return item.__typename === 'ServiceContractItem' && 'serviceId' in item;
  };

  const secondServiceId =
    hasTwoActiveServices?.length === 2 && hasTwoActiveServices.every(isServiceContractItem)
      ? hasTwoActiveServices[0].serviceId === serviceId
        ? hasTwoActiveServices[1].serviceId
        : hasTwoActiveServices[0].serviceId
      : undefined;

  const { data: displayMoveOrder } = useFiberServiceIsMovingQuery({
    variables: {
      input: {
        id: serviceId,
        secondServiceId: secondServiceId,
      },
    },
    skip: !secondServiceId,
  });

  const isAlltSaman = activeOrPendingContract?.variant?.id?.includes('allt');
  const devices = activeOrPendingContract?.contractItems.filter(
    (device) => device.__typename === 'DeviceContractItem',
  );
  const payerNationalId = activeOrPendingContract?.payer?.nationalId;

  if (!data || error) {
    return (
      <>
        <ErrorBanner
          eyebrowTexts={[
            t('errors:contractList.netid.eyebrows.1'),
            t('errors:contractList.netid.eyebrows.2'),
            t('errors:contractList.netid.eyebrows.3'),
          ]}
          titles={[
            t('errors:contractList.netid.titles.1'),
            t('errors:contractList.netid.titles.2'),
            t('errors:contractList.netid.titles.3'),
          ]}
          descriptions={[
            t('errors:contractList.netid.descriptions.1'),
            t('errors:contractList.netid.descriptions.2'),
            t('errors:contractList.netid.descriptions.3'),
          ]}
          icon="zap"
          color={ui?.serviceColor ?? 'attention'}
          showLoading={loading || networkStatus === NetworkStatus.refetch}
          refetchButton={{
            text: t('errors:buttons.refresh'),
            icon: 'refresh',
            onClick: () => refetch(),
          }}
          loadingComponent={
            <>
              <ListBase isLoading gap={3} />
              <ListBase isLoading gap={3} />
              <ListBase isLoading />
            </>
          }
        />
      </>
    );
  }

  return (
    <Box display="flex" flexDirection="column" gap={10}>
      {isStaff && <FiberDevices color={ui?.serviceColor} />}
      {isStaff && (
        <FiberRestrictions
          hasPingAlert={true}
          restriction={activeOrPendingContract?.hasActiveDefault ?? false}
          color={ui?.serviceColor ?? 'purple'}
          nationalId={payerNationalId ?? ''}
          contractId={activeOrPendingContract?.id ?? ''}
          isAlltSaman={activeOrPendingContract?.variant?.productName?.toLowerCase() === 'alltsaman'}
        />
      )}
      {!hasTermination && (
        <FiberAppointment
          fiberOrderId={service?.fiberOrderId ?? ''}
          color={parseMainColor(ui?.serviceColor ?? 'purple')}
        />
      )}
      {hasTermination ? (
        <FiberServiceTermination
          termination={termination}
          terminationRefetch={terminationRefetch}
          hasPingAlert={true}
        />
      ) : (
        <FiberServiceActivate
          fiberOrderId={service?.fiberOrderId ?? ''}
          serviceId={service?.id ?? ''}
          serviceOssId={service?.ossId ?? ''}
          color={parseMainColor(ui?.serviceColor ?? 'purple')}
          shouldRefetchServiceIfActivated={() => refetch()}
        />
      )}
      {displayMoveOrder?.fiberServiceIsMoving && <FiberMoveOrderContainer />}
      <PendingPayerChanges />
      <FiberStatus
        serviceId={service?.id ?? ''}
        color={ui?.serviceColor ?? 'purple'}
        statusCode={activeOrPendingContract?.status ?? ContractStatus.Unknown}
        serviceStatus={service?.status ?? ServiceStatus.Unknown}
        hasDefaults={activeOrPendingContract?.hasActiveDefault ?? false}
      />
      <UsageSummary
        contractId={activeOrPendingContract?.id ?? ''}
        nationalId={service?.user?.nationalId ?? ''}
        color={ui?.serviceColor ?? 'purple'}
        isActive={service?.status === FiberServiceStatus.Active}
      />
      {activeOrPendingContract?.legacySummaryId && (
        <MonthlySummary
          color={ui?.serviceColor ?? 'purple'}
          subscriptionId={activeOrPendingContract?.legacySummaryId ?? ''}
          ossId={service?.ossId ?? ''}
          payerNationalId={payerNationalId || ''}
          isActive={service?.status === FiberServiceStatus.Active}
        />
      )}
      <FiberItems
        color={ui?.serviceColor ?? 'purple'}
        devices={devices as Array<DeviceContractItem>}
        contractId={activeOrPendingContract?.id ?? ''}
        deviceRefetch={contractsRefetch}
        isAlltSaman={isAlltSaman}
      />
      <Discounts
        color={ui?.serviceColor ?? 'purple'}
        contractId={activeOrPendingContract?.id ?? ''}
      />
    </Box>
  );
};

export default inject('ui', 'authentication')(observer(FiberServiceContainer));
